가변 템플릿(Variadic Template)함수 템플릿과 클래스 템플릿에서 인수 개수가 다양할 때 이를 가변(Variadic)이라고 한다.
(임의 개수의 인수에 동작하는 함수 템플릿과 클래스 템플릿)
이는 인수의 최소 개수는 지정하지만, 인수의 최대 개수를 지정하지 않는다.
또한 템플릿 인수는 다른 타입(또는 정수 타입의 상수)이 될 수 있다.
template <typename T>
inline T sum(T t){ return t; }
template <typename T, typename ...P>
inline T sum(T t, P... p){
return t+sum(p...);
}
가변 템플릿은 내부적으로 재귀를 통해 처리한다.
매개변수 팩(Parameter Pack)을 분해하고, 부분집합을 다룬다.
일반적으로 하나의 요소를 분리해 나머지 요소의 결과와 합친다.
재귀를 끝내기 위해서 단일 인수에 대한 오버로드를 필요로 한다.
줄임표 연산자 ‘…’ (…가 왼쪽에 있을 때는 패킹, …가 오른쪽에 있을 때는 언패킹을 의미한다)typename …P : 복수의 타입 인수를 타입 팩 P에 패킹한다.
<P…> : 클래스나 함수 템플릿을 인스턴스화할 때 P를 언패킹
P …p: 변수 팩 p에 여러 함수 인수를 패킹
sum(p…) : 변수 팩 p를 언패킹하고 여러 인수로 sum 함수를 호출한다.
auto s=sum(-7, 3.7f, 9u, -2.6);
std::cout<<"s is "<<s<<" and its tpye is "<<typeid(s).name()<<'\n';
리턴 타입을 첫번 째 인수와 동일하게 사용하였기 때문에 첫번째 인수 int형으로 반환함
auto s2=sum(-7, 3.7f, 9u, -42.6);
std::cout<<"s2 is "<<s2<<" and its type is "<<typeid(s2).name()<<'\n';
따라서 리턴타입을 수정하는 것이 좋다.
sizeof …컴파일 타임에 매개변수 팩의 인수 개수를 계산하기 위해 함수와 같은 표현식 sizeof …를 사용할 수 있다.
template <typename ...P>
void count(P ...p){
std::cout<<"You have "<<sizeof ...(P)<<" parameters.\n";
}